﻿using System;

namespace DAL.Gateway
{
    public class Oracle : GDatos, IGDatos
    {
        static readonly System.Collections.Hashtable ColComandos = new System.Collections.Hashtable();
        /// <summary>
        /// Pendiente verificar la estructura
        /// </summary>
        public override string CadenaConexion
        {
            get
            {
                if (MCadenaConexion.Length == 0)
                {
                    if (MBase.Length != 0 && MServidor.Length != 0)
                    {
                        //Data Source=MyOracleDB;User Id=myUsername;Password=myPassword;Integrated Security=no; 
                        var sCadena = new System.Text.StringBuilder("");
                        sCadena.Append("Data Source=<SERVIDOR>;");
                        sCadena.Append("initial catalog=<BASE>;");
                        sCadena.Append("User Id=<USER>;");
                        sCadena.Append("Password=<PASSWORD>;");
                        sCadena.Replace("<SERVIDOR>", Servidor);
                        sCadena.Replace("<BASE>", Base);
                        sCadena.Replace("<USER>", Usuario);
                        sCadena.Replace("<PASSWORD>", Password);

                        return sCadena.ToString();
                    }
                    throw new Exception("No se puede establecer la cadena de conexión en la clase DatosOracle");
                }
                return null;
            }// end get
            set
            { MCadenaConexion = value; } // end set
        }

        protected override System.Data.IDbConnection CrearConexion(string cadena)
        {
            return new System.Data.OracleClient.OracleConnection(cadena);
        }

        protected override System.Data.IDbCommand Comando(string procedimientoAlmacenado)
        {
            System.Data.OracleClient.OracleCommand com;
            if (ColComandos.Contains(procedimientoAlmacenado))
                com = (System.Data.OracleClient.OracleCommand)ColComandos[procedimientoAlmacenado];
            else
            {
                var con2 = new System.Data.OracleClient.OracleConnection(Conexion.ConnectionString);
                con2.Open();
                com = new System.Data.OracleClient.OracleCommand(procedimientoAlmacenado, con2)
                {
                    CommandType = System.Data.CommandType.StoredProcedure
                };
                System.Data.OracleClient.OracleCommandBuilder.DeriveParameters(com);
                con2.Close();
                con2.Dispose();
                ColComandos.Add(procedimientoAlmacenado, com);
            }//end else
            com.Connection = (System.Data.OracleClient.OracleConnection)Conexion;
            com.Transaction = (System.Data.OracleClient.OracleTransaction)MTransaccion;
            return com;
        }

        protected override System.Data.IDbCommand ComandoSql(string comandoSql)
        {
            var com = new System.Data.OracleClient.OracleCommand(comandoSql, (System.Data.OracleClient.OracleConnection)Conexion, (System.Data.OracleClient.OracleTransaction)MTransaccion);
            return com;
        }

        protected override System.Data.IDataAdapter CrearDataAdapter(string procedimientoAlmacenado, params object[] args)
        {
            var da = new System.Data.OracleClient.OracleDataAdapter((System.Data.OracleClient.OracleCommand)Comando(procedimientoAlmacenado));
            if (args.Length != 0)
                CargarParametros(da.SelectCommand, args);
            return da;
        }

        protected override System.Data.IDataAdapter CrearDataAdapterSql(string comandoSql)
        {
            var da = new System.Data.OracleClient.OracleDataAdapter((System.Data.OracleClient.OracleCommand)Comando(comandoSql));
            return da;
        }

        protected override void CargarParametros(System.Data.IDbCommand com, object[] args)
        {
            for (int i = 1; i < com.Parameters.Count; i++)
            {
                var p = (System.Data.OracleClient.OracleParameter)com.Parameters[i];
                p.Value = i <= args.Length ? args[i - 1] : null;
            }
        }
          /*
         * Definiremos dos constructores especializados, uno que reciba como argumentos los valores de Nombre del Servidor 
         * y de base de datos que son necesarios para acceder a datos, y otro que admita directamente la cadena de conexión completa.
         * Los constructores se definen como procedimientos públicos de nombre New.
         */
        public Oracle()
        {
            Base = "";
            Servidor = "";
            Usuario = "";
            Password = "";
        }// end DatosOracle


        public Oracle(string cadenaConexion)
        { CadenaConexion = cadenaConexion; }// end DatosOracle


        public Oracle(string servidor, string @base)
        {
            Base = @base;
            Servidor = servidor;
        }// end DatosOracle


        public Oracle(string servidor, string @base, string usuario, string password)
        {
            Base = @base;
            Servidor = servidor;
            Usuario = usuario;
            Password = password;
        }// end DatosOracle
    }
}
